<?php
/**
 * Created by PhpStorm.
 * User: 钊鑫
 * Date: 2019/1/23
 * Time: 10:13
 */
namespace app\api\service;
use app\api\model\SysConfig as SysConfigModel;
use app\lib\enum\Scope as ScopeEnum;
use app\lib\exception\Base as BaseException;
use app\api\model\Homeuser as HomeuserModel;
use think\Exception;

//小程序+公众号Token
class WxToken extends Token
{
    protected $code;
    protected $wxAppID;
    protected $wxAppSecret;
    protected $wxExpire;
    protected $wxLoginUrl;

    function __construct($code,$id = ''){
        $wxconfig=$this->wxconfig();
        $this->code = $code;
        $this->id = $id;
        $this->wxAppID = $wxconfig['wx_app_id'];
        $this->wxAppSecret = $wxconfig['wx_app_secret'];
        $this->wxTokenExpire = $wxconfig['wx_token_expire'];//token缓存有效时间
        //sprintf函数是把百分号（%）符号替换成一个作为参数进行传递的变量：%s=字符串,%u=正整数
        $this->wxLoginUrl = sprintf(config('setting.wx_login_url'),$this->wxAppID,
            $this->wxAppSecret, $this->code);
    }

    //获取token，openid
    public function getToken(){
        //注意code是临时的，所以向微信服务器提交只能使用一次
        $result = curl_get($this->wxLoginUrl);
        $wxResult = json_decode($result, true);
        if (empty($wxResult))
        {
            throw new Exception('获取session_key及openID时异常，微信内部错误');
        }else{
            $loginFail = array_key_exists('errcode', $wxResult);
            if ($loginFail) {
                $this->WxError($wxResult);
            } else {
                return $this->grantToken($wxResult);
            }
        }
    }

    //openid，uid放入缓存，$token做缓存键名;
    private function grantToken($wxResult){
        $openid = $wxResult['openid'];
        $user = HomeuserModel::getByOpenID($openid,$this->id);
        if($user>0){
            $uid = $user;
        } else{
            return false;
            //$uid = $this->newUser($openid);
        }
        $cachedValue = $this->setWxCache($wxResult,$uid);
            $token = $this->saveCache($cachedValue);
        return $token;
    }

    //组合uid，openid，权限
    private function setWxCache($wxResult, $uid){
        $cache = $wxResult; //微信的3个返回值
        $cache['uid'] = $uid;
        $cache['scope'] = ScopeEnum::User;  // scope=16 代表App用户的权限数值
        return $cache;
    }

    //放入缓存
    private function saveCache($cachedValue){
        $key = self::generateToken();//生成token
        $value = json_encode($cachedValue);
        $request = cache($key, $value);//第三参数是时效区
        if(!$request){
            throw new BaseException([
                'msg' => '服务器缓存异常'
            ]);
        }
        return $key;
    }

    private function newUser($openid){
        $user = UserModel::create([
            'openid' => $openid
        ]);
        return $user->id;
    }

    //微信错误信息解析后抛出
    private function WxError($wxResult)
    {
        throw new BaseException(
            [
                'msg' => $wxResult['errmsg'],
                'errorCode' => $wxResult['errcode']
            ]);
    }

    //从数据库获取小程序配置信息
    public function wxconfig(){
        $where['is_use']=1;
        $where['key']=['wx_app_id','wx_app_secret','wx_token_expire'];
        $data = SysConfigModel::where($where)->select();
        if(!$data || count($data)<1){
            throw new BaseException(['msg'=>'API中无小程序配置信息']);
        }
        $arr=[];
        foreach ($data as $k=>$v){
            $arr[$v['key']] = $v['value'];
        }
        return $arr;
    }

}